package com.exm.collectcodenew.web.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.exm.collectcodenew.common.vo.ResultMap;
import com.exm.collectcodenew.web.entity.Works;
import com.exm.collectcodenew.web.mapper.WorkByMapper;
import com.exm.collectcodenew.web.service.WorkCommentDetailByMapperService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.stream.Collectors;

@Service
public class WorkCommentDetailByMapperServiceImpl implements WorkCommentDetailByMapperService {
    @Autowired
    private WorkByMapper workByMapper;
    @Override
    public ResultMap selectDetails(Works works) {
        IPage<Works> page =null;
        if(!ObjectUtils.isEmpty(works.getCurrent())&& !ObjectUtils.isEmpty(works.getSize())){
            page= new Page(works.getCurrent(),works.getSize());
        }else{
            return ResultMap.fail("请设置分页参数");
        }
        LocalDate startDate = LocalDate.parse(works.getStartDate());
        LocalDate endDate = LocalDate.parse(works.getEndDate());
        if(ObjectUtils.isEmpty(startDate)||ObjectUtils.isEmpty(endDate)){
            return ResultMap.fail("请填写开始时间和结束时间");
        }
        if(startDate.isAfter(endDate)){
            return ResultMap.fail("开始时间不能晚于结束时间");
        }
        List<Map<String,Object>> dailyCountMap=workByMapper.getDailyCount(works,buildDailyCount(startDate,endDate));
        //计算符合条件的总条数
        long totalNum=dailyCountMap.stream().mapToLong(map->{
            Long num =(Long)map.getOrDefault("selectedcount",0);
            return num.longValue();
        }).sum();
       SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Map<Date,Long> pureCountMap=dailyCountMap.stream().filter(map->{
            Long count=(Long) map.getOrDefault("selectedcount",0);
            return count>0;
            }).collect(Collectors.toMap(
                    //键：将字符串转换成Date对象
                map->{
                    try {
                      return  sdf.parse((String)map.get("selecteddate"));
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                },
                //值：获取计数并转换成Long
                map->{
                    Long num =  (Long)map.get("selectedcount");
                    return num.longValue();
                },
                //处理重复日期并合并策略（这里选择保留第一个值）
                (existing,replacement)->existing,
                        //这里指返回的map
                HashMap::new));
        long start=(works.getCurrent()-1)*works.getSize();
        long end=0;
        if(totalNum>works.getCurrent()*works.getSize()){
            end=works.getCurrent()*works.getSize();
        }else{
            end=totalNum;
        }
        long globalOffset = 0;//从第globalOffset条开始查询
        //根据分页信息，计算查询的当前页在哪个日期区间内
        List<String> currentPageselecteddates = findDatesInterval(pureCountMap,start,end,globalOffset);
        long globalLimit= end-start+1;
        List<Works> result = workByMapper.getCurrentPageData(works,currentPageselecteddates,globalOffset,globalLimit);
        page.setRecords(result);
        page.setTotal(totalNum);
        return ResultMap.success(page);
    }
    //查找数据区间在哪些日期中存在
    private List<String> findDatesInterval(Map<Date, Long> dailyCountMap, long start, long end, long globalOffset) {
        List<String> result = new ArrayList<>();
        long currentStart=1;//索引从1开始
        List<Date> sortedDates= dailyCountMap.keySet().stream().sorted().collect(Collectors.toList());
        boolean includeStart = true;//用于设置第一次有交集时算 globalOffset
        for (Date date : sortedDates) {
            long count = dailyCountMap.get(date);
            long currrentEnd = currentStart+count-1;
            //检查区间是否有重叠
            if(hasOverLap(currentStart,currrentEnd,start,end)){
                if (includeStart){
                    globalOffset=start-currentStart;
                    includeStart = false;
                }
                result.add(new SimpleDateFormat("yyyyMMdd").format(date));
            }
            currentStart=currrentEnd+1;
        }
        return result;
    }
    private boolean hasOverLap(long start, long end, long start1, long end1) {
        return Math.max(start,start1)<=Math.min(end,end1);
    }
    //根据日期区间获取所有需要查询的表名后缀
    private List<String > buildDailyCount(LocalDate startDate, LocalDate endDate) {
        List<String> tableNames = new ArrayList<>();
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            tableNames.add(currentDate.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            currentDate = currentDate.plusDays(1);
        }
        return tableNames;
    }
}
